﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication27
{
    public static class RSA
    {
        public static int makekeys(Liczba a, Liczba b)
        {
            Liczba jeden=new Liczba("1",a.system);
            Liczba n = a * b;
            Liczba euler = (a - jeden) * (b - jeden);
            Liczba e = new Liczba("1 0 255", a.system);
            Liczba d = RozszerzonyAlgorytmEuklidesa.zrob(e, euler);


           

            io IO = new io();
            try
            {
                IO.zapiszklucze(n.ToString(), e.ToString(), d.ToString(), a.ToString(), b.ToString());
            }
            catch (Exception x)
            {
               string  dd = "BLAD";
                IO.zapiszklucze(n.ToString(), e.ToString(), dd, a.ToString(), b.ToString());
               
               
            }

            return n.element.Count();
          


            

            

        }

        public static List<Liczba> odszyfruj(string path)
        {
            io IO = new io();
            byte[] dozaszyfrowania = IO.wczytaj2(path);
            List<string> klucze = IO.wczytajklucze();


            klucze[2] = klucze[2].Remove(klucze[2].Length - 1, 1);
            klucze[0] = klucze[0].Remove(klucze[0].Length - 1, 1);

            klucze[3] = klucze[3].Remove(klucze[3].Length - 1, 1);
            klucze[4] = klucze[4].Remove(klucze[4].Length - 1, 1);

            Liczba b = new Liczba(klucze[2], 256);
            Liczba n = new Liczba(klucze[0], 256);

            Liczba p = new Liczba(klucze[3], 256);
            Liczba q = new Liczba(klucze[4], 256);

            Liczba jeden = new Liczba("1",256);

            Liczba m1potega = b % (q - jeden);
            Liczba m2potega = b % (p - jeden);

            Liczba dox = RozszerzonyAlgorytmEuklidesa.zrob(q, p);


            List<Liczba> zakodowane = new List<Liczba>();
            int i = 1;

                int dlugosc = (int)dozaszyfrowania[0];
                int j = 1;
               
                while (i < dozaszyfrowania.Length)
                {
                    string temp = "";

                    for (; i < dlugosc+j; i++)
                    {
                        temp += Convert.ToString(dozaszyfrowania[i]) + " ";
                    }
                    temp = temp.Remove(temp.Length - 1, 1);


                    Liczba k = p * q;

                    Liczba a = new Liczba(temp, 256);
                   // Liczba cc=PotegowanieModulo.modulo(a,b,n);


                    Liczba m1 = (a % q);
                    m1 = PotegowanieModulo.modulo(m1, m1potega, q);

                    Liczba m2 = (a % p);
                    m2 = PotegowanieModulo.modulo(m2, m2potega, p);

                    Liczba x = (m2 - m1);
                    while (x.znak == '-') x = x + p;
                    x=(x* dox) % p;

                    Liczba c = m1 + x * q;
                


                    zakodowane.Add(c);

                    try
                    {
                        dlugosc += (int)dozaszyfrowania[i++];
                    }
                    catch (Exception e) { };
                    j++;
                }





                return zakodowane;



        }

        public static List<Liczba> szyfruj(string path)
        {
            io IO = new io();
            byte[] dozaszyfrowania=IO.wczytaj(path);
            List<string> klucze = IO.wczytajklucze();


            klucze[0] = klucze[0].Remove(klucze[0].Length - 1, 1);
            klucze[1] = klucze[1].Remove(klucze[1].Length - 1, 1);
            klucze[2]= klucze[2].Remove(klucze[2].Length-1,1);

          
       

            Liczba n = new Liczba(klucze[0], 256);
            Liczba e = new Liczba(klucze[1], 256);
            Liczba d = new Liczba(klucze[2], 256);


            List<Liczba> zakodowane = new List<Liczba>();
             int dotego=(dozaszyfrowania.Length / (n.element.Count()-1));
            int i = 0;
            for (int j = 1; j <= dotego; j++)
            {
                string temp="";
                for (int x = 0; x < n.element.Count()-1; x++)
                {
                    temp += Convert.ToString(dozaszyfrowania[i++]) + " ";
                }
                temp=temp.Remove(temp.Length-1,1);
              
               
                   
                  
                    Liczba m = new Liczba(temp, 256);
                 

                    Liczba c = PotegowanieModulo.modulo(m, e, n);
                    ulong dlugosc=(ulong)c.element.Count();
                    List<ulong> temporary=new List<ulong>();
                    temporary.Add(dlugosc);
                    Liczba dl = new Liczba(temporary, c.system);
                    //dl = PotegowanieModulo.modulo(dl, e, n);
                   // c.element.Insert(0, dlugosc);
                  //  Liczba xx = PotegowanieModulo.modulo(c, d, n);








                    zakodowane.Add(dl);
                    zakodowane.Add(c);

            }
            string  temp2 = "";
            for (; i < dozaszyfrowania.Length; i++)
            {
                temp2 += Convert.ToString(dozaszyfrowania[i]) + " ";
            }


            if (temp2.Length > 0)
            {



                temp2 = temp2.Remove(temp2.Length - 1, 1);
                Liczba m = new Liczba(temp2, 256);
               
               
               


                Liczba c = PotegowanieModulo.modulo(m, e, n);
               // Liczba x = PotegowanieModulo.modulo(c, d, n);
                 ulong dlugosc = (ulong)c.element.Count();
                List<ulong> temporary = new List<ulong>();
                temporary.Add(dlugosc);
                Liczba dl = new Liczba(temporary, c.system);
               // Liczba x = PotegowanieModulo.modulo(c, d, n);


               zakodowane.Add(dl);
               zakodowane.Add(c);
            }

            return zakodowane;
           
            

        }

       
    }
}
